package dongshi.daddy.zookeeper;

import dongshi.daddy.zookeeper.watcher.MyWatcher;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;

public class ZkMain {
    //连接地址及端口号
    private static final String SERVER_HOST = "127.0.0.1:5181";

    //会话超时时间
    private static final int SESSION_TIME_OUT = 2000;

    public static void main(String[] args) throws Exception {
//        create();
//        query();
//        update();
//        del();
//        testUpdateWatcher();

//        testUpdateWatcherSequential();
//        createPersistentSequential();
//        createPersistentSequential();

//        createTwice();
        testDeleteWatcher();
    }

    private static void testDeleteWatcher() throws Exception {
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        String path = "/java" + Math.random();
        System.out.println(zooKeeper.create(path, "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
        ZooKeeper zooKeeper1 = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        // 其他客户端监听
        zooKeeper1.exists(path, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("我是exists()方法的监听器：" + event.getType().name());
            }
        });
        Stat stat = new Stat();
        zooKeeper.getData(path, false, stat);
//        zooKeeper.delete(path, stat.getVersion());
        // 连接关闭自动删除
        zooKeeper.close();
        Thread.sleep(Integer.MAX_VALUE);
    }
    private static void createTwice() throws Exception {
        //参数一：服务端地址及端口号
        //参数二：超时时间
        //参数三：监听器
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        System.out.println(zooKeeper.create("/java111", "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
        System.out.println(zooKeeper.create("/java111", "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
        System.out.println("新增ZNode成功");
        zooKeeper.close();
    }

    private static void createPersistentSequential() throws IOException, KeeperException, InterruptedException {
        //参数一：服务端地址及端口号
        //参数二：超时时间
        //参数三：监听器
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
//        zooKeeper.create("/java111", "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
//        zooKeeper.create("/java111", "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
//        System.out.println("新增ZNode成功");
        zooKeeper.close();
    }

    // 一个事件，设置多个watcher
    private static void testUpdateWatcherSequential() throws IOException, KeeperException, InterruptedException {
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        zooKeeper.exists("/java", new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("我是exists()方法的监听器");
            }
        });
        Stat stat = new Stat();
        zooKeeper.getData("/java", new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("我是getData()方法的监听器");
            }
        }, stat);
        //对ZNode进行更新数据的操作，触发监听器
        zooKeeper.setData("/java", "fly".getBytes(), stat.getVersion());
    }

    private static void testUpdateWatcher() throws Exception {
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        zooKeeper.exists("/java", new MyWatcher());
        //对ZNode进行更新数据的操作，触发监听器
        zooKeeper.setData("/java", "fly".getBytes(), -1);
    }

    private static void del() throws IOException, KeeperException, InterruptedException {
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        Stat stat = new Stat();
        zooKeeper.getData("/java", false, stat);
//删除ZNode
        zooKeeper.delete("/java", stat.getVersion());
    }

    private static void update() throws IOException, KeeperException, InterruptedException {
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        //获取节点描述信息
        Stat stat = new Stat();
        zooKeeper.getData("/java", false, stat);
        System.out.println("更新ZNode数据...");
        //更新操作，传入路径，更新值，版本号三个参数,返回结果是新的描述信息
        Stat setData = zooKeeper.setData("/java", "fly!!!".getBytes(), stat.getVersion());
        System.out.println("更新后的版本号为：" + setData.getVersion());//更新后的版本号为：1
    }

    private static void query() throws IOException, KeeperException, InterruptedException {
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        //数据的描述信息，包括版本号，ACL权限，子节点信息等等
        Stat stat = new Stat();
        //返回结果是byte[]数据，getData()方法底层会把描述信息复制到stat对象中
        byte[] bytes = zooKeeper.getData("/java", false, stat);
        //打印结果
        System.out.println("ZNode的数据data:" + new String(bytes));//Hello World
        System.out.println("获取到dataVersion版本号:" + stat.getVersion());//默认数据版本号是0
    }

    private static void create() throws IOException, KeeperException, InterruptedException {
        //参数一：服务端地址及端口号
        //参数二：超时时间
        //参数三：监听器
        ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //获取事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //判断是否是连接事件
                if (Event.KeeperState.SyncConnected == state) {
                    Event.EventType type = watchedEvent.getType();
                    if (Event.EventType.None == type) {
                        System.out.println("zk客户端已连接...");
                    }
                }
            }
        });
        zooKeeper.create("/java", "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("新增ZNode成功");
        zooKeeper.close();
    }
}
